package com.companyName.generator;

import org.apache.commons.logging.LogFactory;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;

public class CodeGenerator {
    private final static org.apache.commons.logging.Log log = LogFactory.getLog(CodeGenerator.class);

    private static String REPLACE_FILE_CONTEXT_PATTERN = "^(import|package|.*companyName.*|<%.*import.*=|.*com.*dao.*|\\s*<.*>fw\\-.*<.*>).*";
    private static String REPLACE_FILE_CONTEXT_PATTERN_DB = "^(\\s*#\\{\\$.*\\}).*";


    private static String SAMPLE_PLACEHOLDER = "sample|fw-sample";
    private static String COMPANY_PLACEHOLDER = "companyName";//"company-name";

    /**
     * 主程序
     */
    public void generate(boolean plugins,String sampleDir, String targetDir, String projectName, String companyName, String txtDbUrl, String txtUserName, String txtPassword, String txtPluginsName) {
        File sampleDirFile = new File(sampleDir);
        if (!sampleDirFile.exists() || !sampleDirFile.isDirectory()) {
            log.error(sampleDir + " is not a dirctory.(源目录不存在)");
            return;
        }

        File targetDirFile = new File(targetDir);
        if(plugins){
            if (!targetDirFile.exists() || !targetDirFile.isDirectory()) {
                log.error(targetDir + " is not a dirctory.(目标目录不存在)");
                return;
            }
        }else {
            if (targetDirFile.exists()) {
                log.info("clean sub files of " + targetDir);
                File[] tdrs = targetDirFile.listFiles();
                for (File tdr : tdrs) {
                    if (tdr.isFile()) {
                        tdr.delete();
                    } else {
                        delete(tdr);
                    }
                }
            } else {
                targetDirFile.mkdirs();
            }
        }


        File[] files = sampleDirFile.listFiles(new SampleFileFilter());

        for (File f : files) {
            scanFile(f, targetDir, projectName, companyName, txtDbUrl, txtUserName, txtPassword,txtPluginsName);
        }
    }

    /**
     * 单个文件替换入口
     */
    public static void scanFile(File f, String targetDir, String projectName, String companyName, String txtDbUrl, String txtUserName, String txtPassword, String txtPluginsName) {
        if (f.isDirectory()) {//如果是文件夹
            String dirName = f.getName();
            if(".idea".equals(dirName)){
                log.info(f.getPath() + ":忽略！");
            }else{
                dirName = replacePathPlaceholder(dirName, projectName, companyName);
                File newDir = new File(targetDir, dirName);
                newDir.mkdirs();

                File[] files = f.listFiles(new SampleFileFilter());
                for (File f2 : files) {
                    scanFile(f2, targetDir + File.separator + dirName, projectName, companyName, txtDbUrl, txtUserName, txtPassword, txtPluginsName);
                }
            }
        } else {//如果是文件
            String fName = f.getName();
            String prefix = fName.substring(fName.lastIndexOf(".") + 1);
            if("iml".equals(prefix)){
                log.info(f.getPath() + ":忽略！");
            }else{
                File newFile = new File(targetDir, fName);
                try {
                    newFile.createNewFile();
                    replaceFilePlaceholder(f, newFile, projectName, companyName, txtDbUrl, txtUserName, txtPassword, txtPluginsName);
                } catch (Exception e) {
                    System.err.println(e.getMessage());
                    return;
                }
            }

        }
    }


    /**
     * 文件目录替换
     */
    private static String replacePathPlaceholder(String dirName, String projectName, String companyName) {
        dirName = dirName.replaceAll(COMPANY_PLACEHOLDER, companyName);//替换公司名称
        dirName = dirName.replaceAll(SAMPLE_PLACEHOLDER, projectName);//替换项目名称
        return dirName;
    }

    /**
     * 文件内容
     */
    private static void replaceFilePlaceholder(File sourceFile, File newFile, String projectName, String companyName, String txtDbUrl, String txtUserName, String txtPassword, String txtPluginsName) {
        try (
                Scanner scanner = new Scanner(sourceFile);
                PrintWriter pr = new PrintWriter(new FileWriter(newFile));
        ) {
            String fileName = sourceFile.getName();
            String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                if (line != null) {
                    if (line.matches(REPLACE_FILE_CONTEXT_PATTERN)) {
                        line = line.replaceAll(SAMPLE_PLACEHOLDER, projectName);//替换项目名称
                        line = line.replaceAll(COMPANY_PLACEHOLDER, companyName);//替换公司名称
                    }
                    if ("application.yaml".equals(fileName)) {
                        if (line.matches("^(\\s*url:.*|\\s*username:.*|\\s*password:.*).*")) {
                            line = line.replaceAll("url: ", "#url: ");//配置文件信息
                            line = line.replaceAll("username: ", "#username: ");//配置文件信息
                            line = line.replaceAll("password: ", "#password: ");//配置文件信息
                            log.info(sourceFile.getPath() + ":屏蔽测试库信息 " + line.trim());
                        }
                        if (line.matches("^(\\s*#\\{\\$.*\\}).*")) {
                            line = line.replaceAll("#\\{\\$url\\}", "url: " + txtDbUrl);//DB配置文件信息
                            line = line.replaceAll("#\\{\\$username\\}", "username: " + txtUserName);//DB配置文件信息
                            line = line.replaceAll("#\\{\\$password\\}", "password: " + txtPassword);//DB配置文件信息
                            log.info(sourceFile.getPath() + ": 配置数据库信息" + line.trim());
                        }
                    }
                    if ("pom.xml".equals(fileName)) {
                        if(txtPluginsName.indexOf("dubbo")>=0 || txtPluginsName.indexOf("hessian")>=0) {
                            if (line.matches("^(\\s*<!\\-\\- .*del dubbo replace \\-\\->).*")) {// 删除dubbo和hessian相关不依赖的jar
                                log.info(sourceFile.getPath() + ":删除JAR" + line.trim());
                                continue;
                            }
                            if(txtPluginsName.indexOf("dubbo")>=0) {
                                if (line.matches("^(\\s*<!\\-\\- .*dubbo replace \\-\\->).*")) { //增加dubbo依赖的jar
                                    log.info(sourceFile.getPath() + ":替换JAR" + line.trim());
                                    line = line.replaceAll(line.trim(), ReplaceMap.getReplaceContent(line.trim()));//pom文件
                                }
                            }
                            if(txtPluginsName.indexOf("hessian")>=0) {
                                if (line.matches("^(\\s*<!\\-\\- .*hessian replace \\-\\->).*")) { //增加dubbo依赖的jar
                                    log.info(sourceFile.getPath() + ":替换JAR" + line.trim());
                                    line = line.replaceAll(line.trim(), ReplaceMap.getReplaceContent(line.trim()));//pom文件
                                }
                            }
                        }

                        if(txtPluginsName.indexOf("cat")>=0) {
                            if (line.matches("^(\\s*<!\\-\\- .*cat replace \\-\\->).*")) {
                                log.info(sourceFile.getPath() + ":替换JAR" + line.trim());
                                line = line.replaceAll(line.trim(), ReplaceMap.getReplaceContent(line.trim()));//pom文件
                            }
                        }
                        if(txtPluginsName.indexOf("rabbitmq")>=0) {
                            if (line.matches("^(\\s*<!\\-\\- .*rabbitmq replace \\-\\->).*")) {
                                log.info(sourceFile.getPath() + ":替换JAR" + line.trim());
                                line = line.replaceAll(line.trim(), ReplaceMap.getReplaceContent(line.trim()));//pom文件
                            }
                        }
                    }
                }
                pr.println(line);
            }
        } catch (FileNotFoundException e) {
            System.err.println(sourceFile + " is not found");
            return;
        } catch (IOException e) {
            System.err.println("replace file placeholder error");
            return;
        }

    }

    private void delete(File f) {
        if (f.isFile()) {
            f.delete();
        } else {
            File[] fs = f.listFiles();
            for (File f2 : fs) {
                delete(f2);
            }
            f.delete();
        }
    }
}


